<template>
  <div class="gantt_control">
    <Space>
      <Select v-model:value="skinValue" style="width: 150px" @change="handleChangeSkin">
        <SelectOption value="terrace">默认皮肤</SelectOption>
        <SelectOption value="skyblue">天蓝色</SelectOption>
        <SelectOption value="meadow">草地色</SelectOption>
        <SelectOption value="broadway">百老汇</SelectOption>
        <SelectOption value="material">材料主题</SelectOption>
        <SelectOption value="contrast_white">高对比度主题 - 白色</SelectOption>
        <SelectOption value="contrast_black">高对比度主题 - 黑色</SelectOption>
      </Select>
      <a-button type="primary" preIcon="clarity:zoom-in-line" @click="zoomIn">放大</a-button>
      <a-button preIcon="clarity:zoom-out-line" @click="zoomOut">缩小</a-button>
      <RadioGroup v-model:value="selectedScale" @change="setZoomLevel">
        <Radio value="day" ref="scale1">天</Radio>
        <Radio value="week" ref="scale2">周</Radio>
        <Radio value="month" ref="scale3">月</Radio>
        <Radio value="quarter" ref="scale4">季</Radio>
        <Radio value="year" ref="scale5">年</Radio>
      </RadioGroup>
    </Space>
  </div>
  <div ref="ganttRef" style="width: 100%; height: calc(79vh - 52px)"></div>
</template>

<script lang="ts" setup>
  import { gantt } from 'dhtmlx-gantt';
  import 'dhtmlx-gantt/codebase/dhtmlxgantt.css';
  import { ref, reactive, onMounted } from 'vue';
  import { Space, RadioGroup, Radio, Select, SelectOption } from 'ant-design-vue';
  // 定义侧边标题
  const selectedScale = ref<string>('year');
  const zoomConfig = {
    levels: [
      {
        name: 'day',
        scale_height: 27,
        min_column_width: 80,
        scales: [{ unit: 'day', step: 1, format: '%d %M' }],
      },
      {
        name: 'week',
        scale_height: 50,
        min_column_width: 50,
        scales: [
          {
            unit: 'week',
            step: 1,
            format: function (date) {
              var dateToStr = gantt.date.date_to_str('%d %M');
              var endDate = gantt.date.add(date, -6, 'day');
              var weekNum = gantt.date.date_to_str('%W')(date);
              return '#' + weekNum + ', ' + dateToStr(date) + ' - ' + dateToStr(endDate);
            },
          },
          { unit: 'day', step: 1, format: '%j %D' },
        ],
      },
      {
        name: 'month',
        scale_height: 50,
        min_column_width: 120,
        scales: [
          { unit: 'month', format: '%F, %Y' },
          { unit: 'week', format: 'Week #%W' },
        ],
      },
      {
        name: 'quarter',
        height: 50,
        min_column_width: 90,
        scales: [
          { unit: 'month', step: 1, format: '%M' },
          {
            unit: 'quarter',
            step: 1,
            format: function (date) {
              var dateToStr = gantt.date.date_to_str('%M');
              var endDate = gantt.date.add(gantt.date.add(date, 3, 'month'), -1, 'day');
              return dateToStr(date) + ' - ' + dateToStr(endDate);
            },
          },
        ],
      },
      {
        name: 'year',
        scale_height: 50,
        min_column_width: 30,
        scales: [{ unit: 'year', step: 1, format: '%Y' }],
      },
    ],
  };
  const ganttTasks = reactive({
    data: [
      {
        id: 1,
        text: '任务测试1',
        start_date: '17-01-2020',
        end_date: '19-01-2020',
        duration: 3,
        progress: 0.6,
        open: true,
      },
      {
        id: 2,
        text: '任务测试2',
        start_date: '17-02-2020',
        end_date: '17-03-2020',
        duration: 3,
        progress: 0.4,
        parent: 1,
        open: true,
      },
    ],
  });

  const ganttRef = ref();
  const initGantt = () => {
    // 清空之前的配置
    gantt.clearAll();
    // 设置中文
    gantt.i18n.setLocale('cn');
    // 特殊配置
    gantt.config.grid_width = 550; // 左侧宽度
    gantt.config.columns = [
      { name: 'wbs', label: '大纲', width: 40, template: gantt.getWBSCode },
      { name: 'text', label: '任务名称', tree: true, width: 200, align: 'center' },
      { name: 'start_date', label: '开始时间', width: 90, align: 'center' },
      { name: 'duration', label: '持续时间', width: 50, align: 'center' },
      { name: 'end_date', label: '结束时间', width: 90, align: 'center' },
      { name: 'add', label: '', width: 40 },
    ];
    // 显示配置
    gantt.ext.zoom.init(zoomConfig);
    gantt.ext.zoom.setLevel(selectedScale.value);
    gantt.ext.zoom.attachEvent('onAfterZoom', (level, config) => {
      selectedScale.value = config.name;
    });
    // 初始化甘特图
    gantt.init(ganttRef.value);
    // 渲染数据
    gantt.parse(ganttTasks);
  };
  const zoomIn = () => {
    gantt.ext.zoom.zoomIn();
  };

  const zoomOut = () => {
    gantt.ext.zoom.zoomOut();
  };

  const setZoomLevel = (e) => {
    gantt.ext.zoom.setLevel(e.target.value);
  };
  // 动态设置皮肤
  const skinValue = ref('terrace');

  const handleChangeSkin = (value: string) => {
    const link = document.createElement('link');

    link.onload = () => {
      gantt.resetSkin();
      gantt.render();
    };

    link.rel = 'stylesheet';
    link.type = 'text/css';
    link.id = 'skin';
    link.href = `node_modules/dhtmlx-gantt/codebase/skins/dhtmlxgantt_${value}.css`;

    const existingLink = document.querySelector('#skin');

    if (existingLink) {
      document.head.replaceChild(link, existingLink);
    } else {
      document.head.appendChild(link);
    }

    skinValue.value = value;
  };
  onMounted(() => {
    initGantt();
  });
</script>
<style lang="less" scoped>
  .gantt_control {
    padding: 10px 0 12px;
    background: #ededed;
    text-align: center;
  }

  ::v-deep(div.gantt_cal_light) {
    height: 290px !important;
  }
</style>
